package com.wei.file.serve.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.wei.file.model.R;
import com.wei.file.model.RecycleFileModel;
import com.wei.file.serve.RecycleService;
import com.wei.file.utils.CommonUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RecycleServiceImpl implements RecycleService {

    private static final String DB_FILE_NAME = "recycle.json";

    @Value("${upload.clearTime}")
    private Long clearTime;

    @Value("${upload.url}")
    private String basePath;

    private final List<RecycleFileModel> list;

    public RecycleServiceImpl() {
        List<RecycleFileModel> list1;
        String dbText = getDbText();
        try {
            list1 = CommonUtils.JSONToList(dbText, RecycleFileModel.class);
        } catch (JsonProcessingException e) {
            list1 = new ArrayList<>();
        }
        list = list1;
    }


    private void save() {
        String dbText = CommonUtils.ObjectToJSON(list);
        setDbText(dbText);
    }

    private File getDbFile() {
        String workDirPath = System.getProperty("user.dir");
        return Paths.get(workDirPath, DB_FILE_NAME).toFile();
    }


    private String getDbText() {
        File file = getDbFile();
        if (!file.exists()) {
            return null;
        }
        try {
            return Files.readString(Paths.get(file.getPath()));
        } catch (IOException e) {
            return null;
        }
    }

    private void setDbText(String text) {
        File file = getDbFile();
        try {
            Files.writeString(Paths.get(file.getPath()), text, StandardCharsets.UTF_8);
        } catch (IOException ignore) {
        }
    }


    /**
     * 清理文件
     */
    @Scheduled(cron = "0 0 12 * * ?") // 每天中午12点执行
//    @Scheduled(fixedRate = 5000) //
    private void clearFile() {
        synchronized (list) {
            List<RecycleFileModel> nowList = list.stream()
                    .filter((o) -> o.getAbsolutePath().indexOf(basePath) == 0)
                    .toList();
            nowList.stream()
                    .filter(o -> o.getClearAt() <= System.currentTimeMillis())
                    .forEach(o -> {
                        try {
                            Files.deleteIfExists(Paths.get(o.getAbsolutePath()));
                        } catch (IOException ignore) {
                        }
                    });
            nowList = nowList.stream()
                    .filter(o -> o.getClearAt() > System.currentTimeMillis()
                            && Files.exists(Paths.get(o.getAbsolutePath())))
                    .toList();
            list.clear();
            list.addAll(nowList);
        }
    }


    @Override
    public R addRecycle(String fillPath, String path) {
        synchronized (list) {
            for (var item : list) {
                if (item.getFilePath().equals(path)) {
                    return R.err("该文件已经加入了回收站");
                }
            }
            Path _path = Paths.get(fillPath);
            if (!Files.exists(_path)) {
                return R.err("文件不存在");
            }
            RecycleFileModel model = new RecycleFileModel();
            model.setDeleteAt(System.currentTimeMillis());
            model.setClearAt(System.currentTimeMillis() + clearTime);
            model.setFilePath(path);
            model.setAbsolutePath(fillPath);
            model.setFolder(Files.isDirectory(_path));
            this.list.add(model);
            save();
            return R.success("文件"+path+" 加入回收站成功");
        }
    }

    @Override
    public R withdrawFile(String filePath) {
        synchronized (list) {
            for (var item : list) {
                if (item.getFilePath().equals(filePath)) {
                    list.remove(item);
                    save();
                    if(Files.exists(Paths.get(item.getAbsolutePath()))){
                        return R.success("恢复成功");
                    }else {
                        return R.err("文件已经被删除");
                    }

                }
            }
            return R.err("找不到该文件");
        }
    }

    @Override
    public boolean existsFile(String path) {
        for (var model : list) {
            if (model.getFilePath().equals(path)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean existsAbsFile(String fillPath) {
        for (var model : list) {
            if (model.getAbsolutePath().equals(fillPath)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<RecycleFileModel> getList() {
        return this.list;
    }
}
